#ifndef DATACENTER_H
#define DATACENTER_H

/**
 * @copyright Copyright (c) 2025 
 * CSG Digital Grid Technology (Guangdong) Co., Ltd.
 * @author zhouyan
 * @brief 数据中心模块
*/
#include "sys_inc.h"
#include "tools/m_mutex.h"
#include "rapidjson/document.h"
#include "def.h"
#include "phylink.h"

#define MQTT_MAX_SIZE           (6*1024)

class DataCenterPrivate;
class DataCenter
{
    friend class DataCenterPrivate;
public:
    DataCenter();
    virtual ~DataCenter();

    int init(const char *ip, uint16_t port, const char *user, const char *passwd, const char *clientId);
    int init(const char *client_id);
    void deinit(void);
    bool logined(void) const;
    bool getModelSchema(size_t wait_s);
    void deleteModel(const char *name);
    void getUartInfo(const char *name);
    bool getUartInfo(const char *name, size_t wait_s);
    void setUart(ComSettings *uartinfo_);
    void getModel(const char *name);
    bool getModel(const std::string &name, size_t wait_s);
    void getModels(const std::list<std::string> &names);
    bool getModels(const std::list<std::string> &names, size_t wait_s);
    bool setModel(const char *model_name, const DC::ModelItems &items);
    void getDevGUID(const char *model_name, const char *port,
                    const char *addr, const char *desc=nullptr);
    void getDevGUID(const DC::DevInfo &dev_info);
    void registerDev(const DC::DevInfo &dev_info);
    bool registerDevs(const std::list<DC::DevInfo> &devs);
    void SubYKCmdTopic(void);
    void listenDevRegisterNotify(void);
    void unLinstenDevRegisterNotify(void);
    void SubRemoteServiceInit(void);
    void SubRemoteServiceHandle(void);
    bool getRegister(const char *model_name, size_t wait_s);
    void unregisterDev(
                    std::string& model_name,
                    std::string& port,
                    std::string& addr,
                    std::string& desc);
    void unregisterDev(const char *model_name, const char *port,
                       const char *addr, const char *desc=nullptr);
    void getData(const char *dev_guid);
    void getData(std::list<const char *>devs);
    static std::string GetTimeStamp( struct tm * tm=nullptr );
    static time_t GetTimeStamp(std::string strTm);
    static bool containedItem(const DC::ModelItems &items, const DC::ModelItem &item);
    bool hasModelName(const std::string &name) const;
    bool hasModel(const std::string &name) const;
    void getUartMode(ComSettings &uartinfo);
    const DC::DevInfo* findDevInfo(const std::string &model_name,
                                   const std::string &port,
                                   const std::string &addr,
                                   const std::string &desc) const;
    const DC::ModelItems * findModel(const std::string &model_name) const;
    bool CheckReturnStatus(uint32_t token);
    uint16_t newToken();

protected:
    const std::string &clientId(void) const;

    int subTopic(const char *topic, int qos = 0);
    int subTopic(const std::string &topic, int qos=0) { return subTopic(topic.c_str(), qos); }
    int unsubTopic(const char *topic);
    int sendMsg(const char *topic, const char *msg=nullptr, int qos=0);
    int sendMsg(const std::string &topic, const char *msg=NULL, int qos=0) { return sendMsg(topic.c_str(), msg, qos); }
    int sendMsg(const std::string &topic, const std::string &msg, int qos=0) { return sendMsg(topic.c_str(), msg.c_str(), qos); }
    void getModelSchema(void);
    void getRegister(const char *model_name = nullptr);
    virtual void onConnect();
    virtual void onConnectionLost(const char *cause);
    virtual void onPublicFailure(const char *cause, int code);
    virtual void onSubscribeFailure(const char *cause, int code);
    virtual void onUnsubscribeFailure(const char *cause, int code);
    virtual bool onMsgArrvd(const char *topic, int topic_len,
                            const char *msg, int msg_len);

protected:
    MMutex mtx_;
private:
    DataCenterPrivate *d_;
};

#endif // DATASERVER_H
